package com.maserb.monitor.service.jwQuestion.impl;

import com.maserb.monitor.common.CreateTimeUtils;
import com.maserb.monitor.entity.jwQuestion.JwQuestionEntity;
import com.maserb.monitor.entity.jwQuestion.JwQuestionItemEntity;
import com.maserb.monitor.entity.jwQuestion.JwQuestionOptionEntity;
import com.maserb.monitor.repository.JwQuestion.JwQuestionItemRepository;
import com.maserb.monitor.repository.JwQuestion.JwQuestionOptionRepository;
import com.maserb.monitor.repository.JwQuestion.JwQuestionRepository;
import com.maserb.monitor.service.base.impl.JpaSpecificationServiceImpl;
import com.maserb.monitor.service.jwQuestion.JwQuestionItemService;
import com.maserb.monitor.service.jwQuestion.JwQuestionService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.thymeleaf.util.StringUtils;

import javax.persistence.criteria.*;
import java.util.List;

@Service
public class JwQuestionItemServiceImpl extends JpaSpecificationServiceImpl<JwQuestionItemRepository,
        JwQuestionItemRepository, JwQuestionItemEntity, String>
        implements JwQuestionItemService {

    @Autowired
    JwQuestionService questionService;

    @Autowired
    JwQuestionOptionRepository optionRepository;

    @Autowired
    JwQuestionRepository jwQuestionRepository;

    @Override
    public Page<JwQuestionItemEntity> findAllByParentId(String parentId, Pageable pageable) {
        Specification<JwQuestionItemEntity> specification = new Specification<JwQuestionItemEntity>() {
            @Override
            public Predicate toPredicate(Root<JwQuestionItemEntity> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                Join<JwQuestionItemEntity, JwQuestionEntity> join = root.join("parent", JoinType.LEFT);
                Path<String> pathJoin = join.get("id");
                return criteriaBuilder.equal(pathJoin, parentId);
            }
        };
        Sort sort = new Sort(Sort.Direction.DESC, "orderIndex");
        PageRequest pr = new PageRequest(pageable.getPageNumber(), pageable.getPageSize(), sort);
        return this.findAll(specification, pr);
    }

    public Long findCountByParentId(String parentId) {
        Specification<JwQuestionItemEntity> specification = new Specification<JwQuestionItemEntity>() {
            @Override
            public Predicate toPredicate(Root<JwQuestionItemEntity> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                Join<JwQuestionItemEntity, JwQuestionEntity> join = root.join("parent", JoinType.LEFT);
                Path<String> pathJoin = join.get("id");
                return criteriaBuilder.equal(pathJoin, parentId);
            }
        };
        return this.count(specification);
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void save(JwQuestionItemEntity entity, String parentId) {
        JwQuestionEntity questionEntity = questionService.findOne(parentId);
        entity.setParent(questionEntity);
        entity.setCreateTime(CreateTimeUtils.getCreateTime());

        if (!StringUtils.isEmptyOrWhitespace(entity.getId())) {
            JwQuestionItemEntity my = findOne(entity.getId());
            entity.setOrderIndex(my.getOrderIndex());
        } else {
            Integer count = Math.toIntExact(this.findCountByParentId(parentId));
            entity.setOrderIndex(count + 1);
        }

        repository.save(entity);
    }

    @Override
    public void doDelete(String id) {
        JwQuestionItemEntity entity = this.findOne(id);
        List<JwQuestionOptionEntity> optionList = optionRepository.findByParent(entity);
        optionRepository.deleteAll(optionList);
        this.delete(entity);
    }
}